
if (not Socket) then
	require "litesocket"
end

socket = {}

local udp_mt = {__index={}}
local udp_mtidx = udp_mt.__index

function socket.udp()
	local obj = Socket(IPPROTO_UDP)
	
	if (obj) then
		local port = {}
		port.__socket = obj
		
		port.locip = "*"
		port.locport = 0
		
		setmetatable(port, udp_mt)
		
		return port
	end
end

function udp_mtidx:sendto(data, ip, port)
	if (self.__socket) then
		local succ, err = self.__socket:SendTo(data, #data, ip, port)
		
		if (succ) then
			return 1
		else
			return nil, err
		end
	end
end

local RECONCAT_SIZE = 1280

local function reconcat_table(data, len)
	if (len <= RECONCAT_SIZE) then
		return string.char(unpack(data, 1, len))
	else
		for i = 1, len, RECONCAT_SIZE do
			data[(i-1)/RECONCAT_SIZE+1] = string.char(unpack(data, i, math.min(i+(RECONCAT_SIZE-1),len)))
		end
		return table.concat(data, "", 1, math.floor(len / RECONCAT_SIZE))
	end
end

function udp_mtidx:receive()
	if (self.__socket) then
		local data, len = self.__socket:RecvTable()
		
		if (data) then
			return reconcat_table(data, len)
		else
			return nil, len
		end
	end
end

function udp_mtidx:receivefrom()
	if (self.__socket) then
		local data, ip, port, len = self.__socket:RecvFromTable()
		
		if (data) then
			return reconcat_table(data, len), ip, port
		else
			return nil, ip
		end
	end
end

function udp_mtidx:setsockname(ip, port)
	if (self.__socket) then
		local res, err = self.__socket:Bind(ip, port)
		
		if (res) then
			self.locip = ip
			self.locport = port
			
			return 1
		else
			return nil, err
		end
	end
end

function udp_mtidx:settimeout(timeout)
	if (self.__socket) then
		self.__socket:SetTimeout(timeout)
	end
end

function udp_mtidx:getsockname()
	if (self.__socket) then
		return self.locip, self.locport
	end
end

function udp_mtidx:close()
	if (self.__socket) then
		self.__socket:Close()
		self.__socket = nil
	end
end

return socket
